package com.pz.gulimall.auth.service;

import com.alibaba.druid.util.StringUtils;
import com.pz.gulimall.auth.feign.MemberFeign;
import com.pz.gulimall.auth.feign.SmsFeign;
import com.pz.gulimall.auth.vo.req.UserRegistReqVo;
import com.pz.gulimall.common.exception.BizCodeEnum;
import com.pz.gulimall.common.exception.RRException;
import com.pz.gulimall.common.to.RegisterMemberTo;
import com.pz.gulimall.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class RegistService {
    @Autowired
    private SmsFeign smsFeign;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private MemberFeign memberFeign;

    public R getCheckCode(String phoneNumber) {
        //判断账号是否被注册
        try {
            R r = memberFeign.queryMember(phoneNumber);
            if(r.getCode() == 0){
                //存在用户
                return R.error(BizCodeEnum.AUTH_REGISTER_MEMBER_EXISTED.getCode(), BizCodeEnum.AUTH_REGISTER_MEMBER_EXISTED.getMsg());
            }
        } catch (Exception e) {
            throw new RRException(BizCodeEnum.AUTH_RPC_MEMBER_FAILED.getMsg(), BizCodeEnum. AUTH_RPC_MEMBER_FAILED.getCode());
        }

        //判断这个验证码是否存在
        String key = "CHECKCODE_"+phoneNumber;
        String checkCode = redisTemplate.opsForValue().get(key);
        if(StringUtils.isEmpty(checkCode)){
            return uploadCheck(phoneNumber, key);
        } else {
            String[] temp = checkCode.split("_");
            long currentTime = System.currentTimeMillis();
            if(currentTime - Long.parseLong(temp[1]) < 60000){
                //还没有超过过期时间(60s内不可再发)
                return R.error(BizCodeEnum.CHECKCODE_CATNOTSEND.getCode(), BizCodeEnum.CHECKCODE_CATNOTSEND.getMsg());
            } else {
                //更新验证码
                return uploadCheck(phoneNumber, key);
            }
        }
    }

    public R uploadCheck(String phoneNumber, String key){
        // checkcode: checkcode_设置时间
        //生成6位随记编码+系统时间，系统时间用来防止前端为过有效时间去发送请求
        String randCheckcode = UUID.randomUUID().toString().substring(0,5);
        String checkCode = randCheckcode+"_"+System.currentTimeMillis();
        try {
            R ans = smsFeign.sms(phoneNumber, randCheckcode);
            if(ans.getCode()==0){
                redisTemplate.opsForValue().set(key,checkCode, 5, TimeUnit.MINUTES);
                return R.ok("短信发送成功，请注意查收！");
            }else {
                log.error("短信服务异常--{}", ans.getMsg());
                throw new RRException(BizCodeEnum.THIRDPARTY_SMS_EXCEPTION.getMsg()+ans.getMsg(), BizCodeEnum.THIRDPARTY_SMS_EXCEPTION.getCode());
            }
        } catch (Exception e) {
            log.error("远程调用短信服务异常--{}", e.getMessage());
            throw new RRException(BizCodeEnum.CHECKCODE_RPC_THIRDPARTY_FAILED.getMsg()+e.getMessage(), BizCodeEnum.CHECKCODE_RPC_THIRDPARTY_FAILED.getCode());
        }
    }

    /**
     *
     * @param registReqVo
     */
    public R submitRegister(UserRegistReqVo registReqVo) {
        //检查验证码是否正确
        String key = "CHECKCODE_"+registReqVo.getMobile();
        String checkcode = redisTemplate.opsForValue().get(key);
        if(checkcode!=null && checkcode.split("_")[0].equals(registReqVo.getCheckCode())){
            RegisterMemberTo to = new RegisterMemberTo();
            BeanUtils.copyProperties(registReqVo, to);
            try {
                R ans = memberFeign.saveRegister(to);
                if(ans.getCode() != 0){
                    return R.error(ans.getCode(), ans.getMsg());
                } else {
                    //删除掉验证码缓存
                    redisTemplate.delete(key);
                    return R.ok("注册成功！");
                }
            } catch (Exception e) {
                log.error("调用 member 远程服务失败--{}", e.getMessage());
                throw new RRException(BizCodeEnum.AUTH_RPC_MEMBER_FAILED.getMsg(), BizCodeEnum. AUTH_RPC_MEMBER_FAILED.getCode());
            }

        } else {
            throw new RRException(BizCodeEnum.CHECKCODE_MISMATCH.getMsg(), BizCodeEnum.CHECKCODE_ILLEGAL.getCode());
        }
    }
}
